package com.ddpt.permission.dubbo;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lh.center.common.enums.MerchantServiceType;
import com.lh.center.common.exception.CommonException;
import com.lh.center.common.exception.ErrorEnum;
import com.lh.center.permission.api.dubbo.RoleService;
import com.lh.center.permission.api.entity.MerchantAdminUser;
import com.lh.center.permission.api.entity.Permission;
import com.lh.center.permission.api.entity.Role;
import com.lh.center.permission.api.request.RoleQueryRequest;
import com.lh.center.permission.api.request.RoleRequest;
import com.lh.center.permission.api.response.MerchantPermissionResponse;
import com.lh.center.permission.api.response.RoleResponse;
import com.lh.center.permission.api.response.SaasRoleResponse;
import com.lh.center.permission.mapper.RoleMapper;
import com.lh.center.permission.service.MerchantAdminUserService;
import com.lh.center.permission.service.RolePermissionService;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@DubboService
public class DubboRoleServiceImpl implements RoleService {

    @Autowired
    private com.lh.center.permission.service.RoleService roleService;

    @Autowired
    private MerchantAdminUserService merchantAdminUserService;

    @Autowired
    private RolePermissionService rolePermissionService;

    @Autowired
    private RoleMapper roleMapper;

    @Override
    public Page<RoleResponse> queryMerchantRolePageList(RoleQueryRequest queryRequest) {
        queryRequest.setSearchCount(false);
        Long total = roleMapper.queryMerchantRoleTotal(queryRequest);
        if (total != null && total > 0) {
            roleMapper.queryMerchantRolePageList(queryRequest);
            queryRequest.setTotal(total);
        }
        return queryRequest;
    }

    @Override
    public Page<SaasRoleResponse> queryBackAdminRolePageList(RoleQueryRequest queryRequest) {
        queryRequest.setSearchCount(false);
        Long total = roleMapper.queryBackAdminRoleTotal(queryRequest);
        if (total != null && total > 0) {
            Page<SaasRoleResponse> page = roleMapper.queryBackAdminRolePageList(queryRequest);
            for (SaasRoleResponse record : page.getRecords()) {
                //添加权限ids
                List<Long> permissionIds = rolePermissionService.queryPermissionByRole(record.getId()).stream().map(e -> e.getId()).collect(Collectors.toList());
                record.setPermissionIds(permissionIds);
            }
            queryRequest.setTotal(total);
        }
        return queryRequest;
    }

    @Override
    @GlobalTransactional
    public void addNew(RoleRequest roleRequest) {
        Role role = new Role();
        role.setMerchantId(roleRequest.getMerchantId());
        role.setName(roleRequest.getName());
        role.setDescription(roleRequest.getDescription());
        roleService.save(role);
        rolePermissionService.addBatch(role.getId(), roleRequest.getPermissionIds());
    }

    @Override
    @GlobalTransactional
    public void update(RoleRequest roleRequest) {
        Role role = new Role();
        role.setId(roleRequest.getId());
        role.setName(roleRequest.getName());
        role.setDescription(roleRequest.getDescription());
        roleService.updateById(role);
        rolePermissionService.updateBatch(role.getId(),roleRequest.getPermissionIds());
    }

    @Override
    public RoleResponse queryDetail(Long id) {
        RoleResponse response = new RoleResponse();
        Role role = roleService.getById(id);
        response.setId(role.getId());
        response.setName(role.getName());
        response.setDescription(role.getDescription());
        List<Permission> permissions = rolePermissionService.queryPermissionByRole(id);
        Map<MerchantServiceType, List<Permission>> permissionMap = permissions.stream().collect(Collectors.groupingBy(Permission::getMerchantService));
        List<Permission> permissionList;
        List<MerchantPermissionResponse> perList = new ArrayList<>();
        MerchantPermissionResponse cur;
        for(MerchantServiceType type : MerchantServiceType.values()) {
            cur = new MerchantPermissionResponse();
            cur.setServiceType(type);
            perList.add(cur);
            if (CollUtil.isNotEmpty(permissionList = permissionMap.get(type))) {
                cur.setPermissionIds(permissionList.stream().map(Permission::getId).collect(Collectors.toList()));
            }
        }
        response.setPermissionResponses(perList);
        return response;
    }

    @Override
    public SaasRoleResponse querySassDetail(Long id) {
        SaasRoleResponse response = new SaasRoleResponse();
        Role role = roleService.getById(id);
        response.setId(role.getId());
        response.setName(role.getName());
        response.setDescription(role.getDescription());
        List<Permission> permissions = rolePermissionService.queryPermissionByRole(id);
        List<Long> perList = permissions.stream().map(Permission::getId).collect(Collectors.toList());
        response.setPermissionIds(perList);
        return response;
    }

    @Override
    public void deleteRole(RoleQueryRequest queryRequest) {
        Long roleId = queryRequest.getId();
        int count = merchantAdminUserService.count(Wrappers.lambdaQuery(MerchantAdminUser.class).eq(MerchantAdminUser::getRoleId, roleId).eq(MerchantAdminUser::getDeleted, 0));
        if (count > 0) {
            throw new CommonException(ErrorEnum.ROLE_NOT_EMPTY);
        }
        LambdaUpdateWrapper<Role> wrapper = Wrappers.lambdaUpdate(Role.class).eq(Role::getId, roleId).eq(Role::getMerchantId, queryRequest.getMerchantId()).set(Role::getDeleted, 1);
        roleService.update(wrapper);
    }

    @Override
    public List<RoleResponse> querySimpleList(Long merchantId) {
        return roleMapper.querySimpleList(merchantId);
    }
}
